<template>
	<div class="overflow-hidden">
		<n-card title="角色管理" :bordered="false" class="h-full rounded-8px shadow-sm">
			<div class="flex-col h-full">
				<n-grid cols="4" :x-gap="8" item-responsive class="flex flex-1 ">
					<n-grid-item span="1 400:1 600:2 800:3" class="flex-col ">
						<div class=" w-full  ">
							<n-space class="pb-12px" justify="space-between">
								<n-space>
									<n-button type="primary" @click="handleAddTable">
										<icon-ic-round-plus class="mr-4px text-20px" />
										新增
									</n-button>
									<n-button type="error">
										<icon-ic-round-delete class="mr-4px text-20px" />
										删除
									</n-button>
									<n-button type="success">
										<icon-uil:export class="mr-4px text-20px" />
										导出Excel
									</n-button>
								</n-space>
								<n-space align="center" :size="18">
									<n-button size="small" type="primary" @click="getTableData">
										<icon-mdi-refresh class="mr-4px text-16px" :class="{ 'animate-spin': loading }" />
										刷新表格
									</n-button>
									<column-setting v-model:columns="columns" />
								</n-space>
							</n-space>
						</div>
						<div class="h-full  flex">
							<n-data-table :columns="columns" :data="tableData" :loading="loading" :pagination="pagination" size="small"
								:single-line="false" flex-height class="flex-1" />
							<table-action-modal v-model:visible="visible" :type="modalType" :edit-data="editData"
								@on-confirm="() => { getTableData(); }" />

						</div>
					</n-grid-item>
					<n-grid-item span="1" class="  flex-col ">
						<div class="  w-full">
							<n-space class="pb-12px" justify="space-between">
								<n-space>
									<n-gradient-text type="warning">
										当前角色：{{ selectRole?.roleName }}
									</n-gradient-text>
								</n-space>
								<n-space align="center" :size="18">
									<n-button type="success" @click="saveRoleMenu">
										保存
									</n-button>
								</n-space>
							</n-space>
						</div>
						<div class="wh-full border-1 border-solid" style=" border-color: rgba(239, 239, 245, 1);">
							<n-tree block-line cascade checkable expand-on-click :data="treeData" :checked-keys="checkedKeys"
								@update:checked-keys="checkedTree" key-field="id" default-expand-all virtual-scroll
								label-field="displayName" style="height:  700px;" />
						</div>
					</n-grid-item>
				</n-grid>
			</div>
		</n-card>
	</div>
</template>

<script setup lang="tsx">
import { reactive, ref } from "vue";
import type { Ref } from "vue";
import { NButton, NPopconfirm, NSpace } from "naive-ui";
import type { DataTableColumns, PaginationProps } from "naive-ui";
import { fetchRoleList, fetchMenuTreeList, fetchRoleMenus, saveRoleMenus, delRole } from "@/service";
import { useBoolean, useLoading } from "@/hooks";
import ColumnSetting from "../../component/table/column-setting.vue";
import TableActionModal from "./components/table-action-modal.vue";
import type { ModalType } from "./components/table-action-modal.vue";

const { loading, startLoading, endLoading } = useLoading(false);
const { bool: visible, setTrue: openModal } = useBoolean();

const tableData = ref<SystemManagement.Role[]>([]);
const treeData = ref<SystemManagement.MenuTree[]>([]);
const checkedKeys = ref<Array<number>>([]);

const selectRole = ref<SystemManagement.Role>();

function setTableData(data: SystemManagement.Role[]) {
	tableData.value = data;
}
function setTreeData(data: SystemManagement.MenuTree[]) {
	treeData.value = data;
}
async function getTreeData() {

	const { data } = await fetchMenuTreeList();
	if (data) {
		setTreeData(data);
	}
}



async function getTableData() {
	startLoading();
	const { data } = await fetchRoleList();
	if (data) {
		setTableData(data);
		endLoading();
	}
}

const columns: Ref<DataTableColumns<SystemManagement.Role>> = ref([
	{
		type: "selection",
		align: "center",
	},
	{
		key: "index",
		title: "序号",
		align: "center",
		width: 80,
		render: (_, index) => {
			return `${index + 1}`
		}
	},
	{
		key: "roleName",
		title: "角色名",
		align: "center",
	},
	{
		key: "code",
		title: "角色代码",
		align: "center",
	},
	{
		key: "lastModifiedTime",
		title: "最后更新时间",
		align: "center",
	},
	{
		key: "actions",
		title: "操作",
		align: "center",
		width: 200,
		render: (row) => {
			return (
				<NSpace justify={"center"}>
					<NButton size={"small"} onClick={() => handleEditTable(row.id)}>
						编辑
					</NButton>
					<NButton size={"small"} onClick={() => handleLoadMenu(row.id)}>
						权限
					</NButton>
					<NPopconfirm onPositiveClick={() => handleDeleteTable(row.id)}>
						{{
							default: () => "确认删除",
							trigger: () => <NButton size={"small"}>删除</NButton>,
						}}
					</NPopconfirm>
				</NSpace>
			);
		},
	},
]) as Ref<DataTableColumns<SystemManagement.Role>>;

const editData = ref<SystemManagement.Role | null>(null);

function setEditData(data: SystemManagement.Role | null) {
	editData.value = data;
}


const modalType = ref<ModalType>("add");

function setModalType(type: ModalType) {
	modalType.value = type;
}


function handleAddTable() {
	openModal();
	setModalType("add");
	setEditData(null);
}

function handleEditTable(rowId: number) {
	const findItem = tableData.value.find((item) => item.id === rowId);
	if (findItem) {
		setEditData(findItem);
	}
	setModalType("edit");
	openModal();
}

async function handleDeleteTable(rowId: number) {
	await delRole(rowId)
	window.$message?.success(`删除成功`);
	await getTableData();
}

async function handleLoadMenu(rowid: number) {
	const { data } = await fetchRoleMenus(rowid);
	if (data)
		checkedKeys.value = data.menuIds;
	else
		checkedKeys.value = [];

	const findItem = tableData.value.find((item) => item.id === rowid);
	if (findItem) {
		selectRole.value = findItem;
	}
	else {
		selectRole.value = undefined;
	}
}




function checkedTree(keys: Array<number>) {
	checkedKeys.value = [...keys];
}


async function saveRoleMenu() {
	if (selectRole.value) {
		let input: SystemManagement.SaveRoleMenusInput = {
			roleId: selectRole.value.id,
			menuIds: checkedKeys.value
		};
		await saveRoleMenus(input);
		window.$message?.success('保存成功!');

	}
	else {
		window.$message?.warning('请先选择角色!');
	}
}

const pagination: PaginationProps = reactive({
	page: 1,
	pageSize: 10,
	showSizePicker: true,
	pageSizes: [10, 15, 20, 25, 30],
	onChange: (page: number) => {
		pagination.page = page;
	},
	onUpdatePageSize: (pageSize: number) => {
		pagination.pageSize = pageSize;
		pagination.page = 1;
	},
});

function init() {
	getTableData();

	getTreeData();
}

// 初始化
init();
</script>

<style scoped></style>
